// ==UserScript== // @name 💡WebPreview - 信息直达 // @namespace https://ez118.github.io/ // @version 1.3.0 // @description 支持国内主流搜索引擎的搜索结果快速预览(直达网页大纲)。只需点击搜索结果旁的小灯泡按钮,即可在右侧速览窗中快速查看目标网站所含的图片、链接、标题大纲、文本。 // @author ZZY_WISU // @match *://*/* // @connect * // @license GNU GPLv3 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAADZQTFRFAAAAn8LgEG6+SZDMg7HaZaDSgrHZkLrdO4jJZqHTgbLZHnbCdKnWLX/FV5jPLX7FSY/LdKnVpsJ+6QAAABJ0Uk5TACb//8j/yoP//8n/8f/////yflwd4QAAAORJREFUeJy1k9EagyAIhfVYGqnV3v9lp2kLjdrFvnGT4Q8coJTqTMP0rov9nRnYebTn2Z3HCSSGzvAsvwjNACuQIH1lGiRBNU+IALwpAXq4hCUCh0VR3y69ykrZbqCFdTHJUNLd5JRGGeH4q4fAdNkDwgWxWLqY6eSJKBcZYTtmz5tuSa1pGkZkUBrJT621WL/U0vW6+nyDkLRm3/YOqXfXeKP8SRGb0M0u+AV14poCZUlaFNMK3YQ9fGwtjLjPwzaYPPynUomp9shQHv4XZl/Oz8yCGGwwj4yKRbL08zGz48t1rjcZWATm0KKJdwAAAABJRU5ErkJggg== // @run-at document-end // @grant GM_xmlhttpRequest // @grant GM_download // @grant GM_registerMenuCommand // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @require https://update.greasyfork.org/scripts/499192/1402326/jquery_360.js // ==/UserScript== var iconImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAUCAMAAACK2/weAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAHtQTFRFAAAAOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGofOGoffJU8/QAAACl0Uk5TABWJvOy7hhRd8P/tT25TIfzzlXziyPju8c/NgHgY9OMRZvU2WkPQx8o0T8eSAAAAbUlEQVR4nI3OyQ6CQBBF0auASOOEgICoCKLw/19ImqG7TFx4V3UWLymA1dpxXW/jM7YN1Fi409or0wGOJ8vI56xEMYlkykUyI5cMKCSvlJI37g+r6gm1UfPSb7UL39PTC/nJz6SOv/qazuNeXwMWhAmHAXFPJgAAAABJRU5ErkJggg=="; /* 用于存储小灯泡按钮的图片数据 */ const contentEleSelList = { "blog.csdn.net": "#article_content", "zhuanlan.zhihu.com": ".Post-RichTextContainer", "jingyan.baidu.com": "#format-exp", "www.bilibili.com": "#article-content", "zhidao.baidu.com": "#qb-content", "www.cnblogs.com": "#topics", "www.sohu.com": "#mp-editor" }; /* 用于储存指定网站的内容所在父元素(特定博客网站内容优化) */ const VideoSupport = [ ["https://v.youku.com/v_show/*.html", "https://player.youku.com/embed/*"], ["https://v.qq.com/x/page/*.html", "https://v.qq.com/txp/iframe/player.html?vid=*"], ["https://www.bilibili.com/video/BV*/", "https://www.bilibili.com/blackboard/html5mobileplayer.html?bvid=*"], ["https://www.bilibili.com/video/av*/", "https://www.bilibili.com/blackboard/html5mobileplayer.html?aid=*"] ]; /* 用于存储阅读器支持直接播放视频的网站及其嵌入播放器代码 */ /* ============================================= */ /** * 生成随机数 * @param len 长度 * @constructor */ function randomString(len) { len = len || 32; var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; var maxPos = $chars.length; var pwd = ''; for (let i = 0; i < len; i++) { pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; } /** * 标题元素 * @param tag 标签,h1 ==> 1 , h2 ==> 2 * @param title 标题 * @param level 层级 * @param id 随机生成的id * @constructor */ function TitleElement(tag, title, level, id) { this.tag = tag; this.title = title; this.level = level; this.id = id; } /* 是否是标题元素 */ function isTitleTag(tag) { return tag.is("h1, h2, h3, h4, h5, h6, h7"); } /** * 生成大纲 * @param $articleContent 文章容器 * @constructor */ function getOutline($articleContent) { $articleContent = $($articleContent); /** 全部元素 */ var $eles = $articleContent.find("*"); /** 标题元素列表 */ var titleElementArr = new Array(); /** 上一个元素 */ var preTitleElement = null; $.each($eles, function(index, item) { if (isTitleTag($(item))) { var id = randomString(20); var level = 1; var tag = parseInt($(item).get(0).tagName.replace('h', "").replace('H', "")); var title = $(item).text(); if (null != preTitleElement) { var tagPre = preTitleElement.tag; var levelPre = preTitleElement.level; if (tagPre > tag) { level = levelPre - 1; } else if (tagPre < tag) { level = levelPre + 1; } else { level = levelPre; } } if (title.trim().length > 0) { $(item).attr("id", id); var titleElement = new TitleElement(tag, title, level, id); titleElementArr.push(titleElement); preTitleElement = titleElement; } } }) console.log(titleElementArr); return titleElementArr; } /* ============================================= */ function stringToHtml(str) { var parser = new DOMParser(); var doc = parser.parseFromString(str, 'text/html'); return doc; } function mobileDevice(){ var info = navigator.userAgent; var isPhone = /mobile/i.test(info); return isPhone; } function runAsync(url,send_type,data_ry) { var p = new Promise((resolve, reject)=> { GM_xmlhttpRequest({ method: send_type, url: url, headers: {"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"}, data: data_ry, onload: function(response){resolve(response.responseText);}, onerror: function(response){reject("请求失败");} }); }); return p; } function escapeHtml(str) { const htmlEntities = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return str.replace(/[&<>"']/g, (match) => htmlEntities[match]); } function JudgeVideoSupport(url) { var previewFlag = 0; /* 判断是否为支持预览视频的网站 */ for(let i = 0; i < VideoSupport.length; i ++){ if( url.includes( VideoSupport[i][0].split("*")[0] ) ){ return { "state":true, "data":i }; break; } } return { "state":false, "data":-1 }; } function getWebContents(txt) { var links; var images; var content; var outline; /* 获取所有链接 */ /* //这一段代码会把所有链接(包括图片、js、css的链接一并获取) links = txt.match(/href\=\"(https?|http|ftp|file):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g); for(let i = 0; i < links.length; i ++) { links[i] = links[i].replace("href=\"", ""); } */ links = []; txt.replace(/]*href=['"]([^'"]+)[^>]*>/g,function(match, capture){ links.push(capture); }); /* 获取所有图片 */ images = []; txt.replace(/]*src=['"]([^'"]+)[^>]*>/g,function(match, capture){ images.push(capture); }); content = txt; /* 删除多余空格和换行 */ content = content.replace(/\s+/g, ' ').trim().replace(/(rn|r|n){ 2,}/g, '$1n'); /* 获取文本 */ content = txt.replace(/<\/div>/g, "\n") .replace(/<\/table>/g, "\n") .replace(/<\/h3>/g, "\n") .replace(/<\/p>/g, "
\n") .replace(/<\/li>/g, "\n") .replace(/